<template>
	<div>
		<!-- 面包屑导航区 -->
		<el-breadcrumb separator-class="el-icon-arrow-right">
		  <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
		  <el-breadcrumb-item>权限管理</el-breadcrumb-item>
		  <el-breadcrumb-item>角色列表</el-breadcrumb-item>
		</el-breadcrumb>
		<!-- 卡片视图区域 -->
		<el-card>
			<!-- 添加角色按钮区域 -->
			<el-row>
				<el-col>
					<el-button type="primary" @click="addRoledialogVisible=true">添加角色</el-button>
				</el-col>
			</el-row>
			<!-- 角色列表区域 -->
			<el-table :data="roleList" border stripe>
				  <el-table-column type="expand">
					  <template slot-scope="scope">
						  <el-row v-for="(item1,i1) in scope.row.children" :class="['bdbottom',i1===0?'bdtop':'','vcenter']">
							  <!-- 渲染一级权限 -->
							  <el-col :span="5">
								  <el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag>
								  <i class="el-icon-caret-right"></i>
							  </el-col >
							  <!-- 渲染二级和三级权限 -->
							  <el-col :span="19" >
								  <el-row v-for="(item2,i2) in item1.children" :key="item2.id" :class="[i2===0?'':'bdtop','vcenter']">
									  <!-- 通过for循环渲染二级权限 -->
									  <el-col :span="6">
										  <el-tag type="success" closable @close="removeRightById(scope.row,item2.id)">{{item2.authName}}</el-tag>
										  <i class="el-icon-caret-right"></i>
									  </el-col>
									  <el-col :span="18">
										  <!-- 再次 for循环渲染三级权限 -->
										  <el-tag type="warning" v-for="(item3,i3) in item2.children" 
										  :key="i3" closable @close="removeRightById(scope.row,item3.id)">{{item3.authName}}</el-tag>
									  </el-col>
								  </el-row>
							  </el-col>
						  </el-row>
					  </template>
				  </el-table-column>
				  <el-table-column type="index"> </el-table-column>
				  <!-- 添加索引列 -->
			      <el-table-column prop="roleName" label="角色名称"> </el-table-column>
				  <!-- prop是取得userList中每一个对象中的对应属性值 -->
			      <el-table-column prop="roleDesc" label="技术负责人"> </el-table-column>
				  <el-table-column  label="操作" width="300px">
					  <template slot-scope="scope">
						  <el-button type="primary" icon="el-icon-edit" size="mini" @click="editRoleDialog(scope.row.id)">编辑</el-button>
						  <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeRoleById(scope.row.id)">删除</el-button>
						  <el-button type="warning" icon="el-icon-setting" size="mini" @click="showSetRightDialog(scope.row)">分配权限</el-button>
					  </template>
				  </el-table-column>
			</el-table>
		</el-card>
		<!-- 添加角色对话框 -->
		<el-dialog
		  title="添加新角色"
		  :visible.sync="addRoledialogVisible"
		  width="50%"
		  @close="addRoleDialogClosed"
		 >
		 <!-- 内容主体区域，这里有一个匿名插槽 -->
		  <el-form :model="addRoleForm" :rules="addFormRules" ref="addRoleFormRef" label-width="100px">
			<el-form-item label="角色名称" prop="roleName">
			  <el-input v-model="addRoleForm.roleName"></el-input>
			</el-form-item>
			<el-form-item label="技术负责人" prop="roleDesc">
			  <el-input v-model="addRoleForm.roleDesc"></el-input>
			</el-form-item>
		  </el-form>
		  <!-- 底部区域，这里是一个具名插槽 -->
		  <span slot="footer" class="dialog-footer">
		    <el-button @click="addRoledialogVisible= false">取 消</el-button>
		    <el-button type="primary" @click="addRole">确 定</el-button>
		  </span>
		</el-dialog>
		<!-- 修改角色对话框 -->
		<el-dialog
		  title="修改角色信息"
		  :visible.sync="editRoleDialogVisible"
		  width="50%"
		   @close="editRoleDialogClosed"
		 >
		 <!-- 内容主体区域，这里有一个匿名插槽 -->
		<el-form :model="editRoleList" :rules="addFormRules" ref="editRoleListRef" label-width="100px">
				<el-form-item label="角色名称" prop="roleName">
				  <el-input v-model="editRoleList.roleName"></el-input>
				</el-form-item>
				<el-form-item label="技术负责人" prop="roleDesc">
				  <el-input v-model="editRoleList.roleDesc"></el-input>
				</el-form-item>
		</el-form>
		 
		  <!-- 底部区域，这里是一个具名插槽 -->
		  <span slot="footer" class="dialog-footer">
		    <el-button @click="editRoleDialogVisible = false">取 消</el-button>
		    <el-button type="primary" @click="editRoleInfo">修改</el-button>
		  </span>
		</el-dialog>
		
		<!-- 分配角色权限的对话框 -->
		<el-dialog
		  title="分配权限"
		  :visible.sync="setRightDialogVisible"
		  width="50%"
		  @close="btDialogClosed"
		  >
		  <!-- 具体的权限信息 -->
		  <el-tree
		    :data="rightsList"
		    show-checkbox
		    node-key="id"
		    default-expand-all
			:props="treePropes"
			:default-checked-keys="defkeys"
			ref="treeRef"
		    >
		  </el-tree>
		  <span slot="footer">
		    <el-button @click="setRightDialogVisible = false">取 消</el-button>
		    <el-button type="primary" @click="allotRights">确 定</el-button>
		  </span>
		</el-dialog>
	</div>
</template>

<script>
	export default{
		data(){
			return{
				roleList:[],
				addRoledialogVisible:false,
				addRoleForm:{
					roleName:'',
					roleDesc:''
				},
				editRoleList:{},
				editRoleDialogVisible:false,
				setRightDialogVisible:false,
				rightsList:{},
				// 树形控件的属性绑定
				treePropes:{
					label:'authName',
					children:'children'
				},
				//选中的id值数组
				defkeys:[],
				roleId:'',
				addFormRules:{
					roleName:[{ required: true, message: '请输入角色名称', trigger: 'blur' }],
					roleDesc:[{ required: true, message: '请输入技术负责人', trigger: 'blur' }]
				}
			}
		},
		created(){
			this.getRoleList()
		},
		methods:{
			async getRoleList(){
				const{data:res}=await this.$http.get('roles')
				if(res.meta.status!==200)return this.$message.error(res.meta.msg)
				//获取数据成功，就保存到前端上
				this.roleList=res.data
			},
			//发起添加用户的请求
			async addRole(){
				const {data:res}=await this.$http.post('roles',this.addRoleForm)
				if(res.meta.status!==201)return this.$message.error(res.meta.msg)
				this.$message.success(res.meta.msg)
				this.getRoleList()
				this.addRoledialogVisible=false
			},
			addRoleDialogClosed(){
				this.$refs.addRoleFormRef.resetFields()
			},
			//弹出修改角色信息的对话框
			async editRoleDialog(id){
				this.editRoleDialogVisible = true
				const{data:res}=await this.$http.get(`roles/${id}`)
				if(res.meta.status!==200)return this.$message.error(res.meta.msg)
				this.editRoleList=res.data
			},
			//关闭修改角色对话框时
			editRoleDialogClosed(){
				this.$refs.editRoleListRef.resetFields()
			},
			//发起修改角色信息的请求
			async editRoleInfo(){
				const{data:res}=await this.$http.put('roles/'+this.editRoleList.roleId,{
					roleName:this.editRoleList.roleName,
					roleDesc:this.editRoleList.roleDesc
				})
				if(res.meta.status!==200)return this.$message.error(res.meta.msg)
				this.editRoleDialogVisible = false
				this.getRoleList()
				this.$message.success("修改角色信息成功")
			},
			//删除数据
			async removeRoleById(id){
				//弹窗询问是否删除数据
				const confirmResult=await this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
				          confirmButtonText: '确定',
				          cancelButtonText: '取消',
				          type: 'warning'
				        }).catch(err=>err)
				//如果用户确认删除，则返回字符串confirm
				//如果用户确认取消，则返回字符串cancel
				if(confirmResult!=='confirm')return this.$message.info("已经取消了删除")
				const{data:res}=await this.$http.delete('roles/'+id)
				if(res.meta.status!==200)return this.$message.error(res.meta.msg)
				this.getRoleList()
				this.$message.success(res.meta.msg)
			},
			//删除某个三级权限,根据id
			async removeRightById(role,authid){
				//弹窗询问是否删除数据
				const confirmResult=await this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
				          confirmButtonText: '确定',
				          cancelButtonText: '取消',
				          type: 'warning'
				        }).catch(err=>err)
				//如果用户确认删除，则返回字符串confirm
				//如果用户确认取消，则返回字符串cancel
				if(confirmResult!=='confirm')return this.$message.info("已经取消了删除")
				const{data:res}=await this.$http.delete('roles/'+role.id+'/'+'rights/'+authid)
				if(res.meta.status!==200) return this.$message.error(res.meta.msg)
				this.$message.success(res.meta.msg)
				role.children=res.data
			},
			
			//分配角色权限的对话框
			async showSetRightDialog(role){
				//这里把这个role存起来,后续直接使用
				this.roleId=role.id
				//获取所有用户权限的数据
				const{data:res}=await this.$http.get('rights/tree')
				if(res.meta.status!==200)return this.$message.error(res.meta.msg)
				//获取数据成功，就保存到前端上
				this.rightsList=res.data
				//递归获取三级节点的所有权限id
				this.getLeafKeys(role,this.defkeys)
				this.setRightDialogVisible=true
			},
			//通过递归的形式,获取角色下的所有三级权限的id,并保存到defkeys数组中
			getLeafKeys(node,arr){
				//如果当前节点没有children,则是三级节点
				if(!node.children){
					//是三级节点,就把id值存入 arr数组中
					return arr.push(node.id)
				}
				//不是三级节点,则继续往下查找三级节点.直到所有的三级节点遍历结束
				//对每一个children再执行getLeafKeys
				node.children.forEach(item=>this.getLeafKeys(item,arr))
			},
			//每次对话框关闭时,清空这个id的数组
			btDialogClosed(){
				this.defkeys=[]
			},
			//点击之后发起请求,为角色分配权限
			async allotRights(){
				const keys=[
					//三点运算符的作用是展开,本来两个返回的都是数组,现在把它展开了,然后放置在一个数组中
					// 选中的节点的key,返回一个数组
					...this.$refs.treeRef.getCheckedKeys(),
					// 半选中的节点的key,返回一个数组
					...this.$refs.treeRef.getHalfCheckedKeys()
				]
				const idStr=keys.join(",")
				const{data:res}=await this.$http.post(`roles/${this.roleId}/rights`,{
					rids:idStr
				})
				if(res.meta.status!==200)return this.$message.error(res.meta.msg)
				this.$message.success(res.meta.msg)
				this.getRoleList()
				this.setRightDialogVisible=false
			}
		}
	}
</script>

<style lang="less" scoped>
	.el-tag{
		margin:7px;
	}
	.bdtop{
		border-top: 1px solid #eee;
	}
	.bdbottom{
		border-bottom: 1px solid #eee;
	}
	.vcenter{
		display: flex;
		align-items: center;
	}
</style>
